﻿//Copyright (c) 2009, Andreas Grünwald
//All rights reserved.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.Text;
using Microsoft.Win32;

namespace yaTDL.Core
{
    /// <summary>
    /// A class for some events, that might be important application-wide.
    /// </summary>
    public static class ApplicationEvents
    {

        /// <summary>
        /// Initializes ApplicationEvents.
        /// </summary>
        static ApplicationEvents()
        {
            //Initializes all properties related to the DateChanged event.
            DateChanged_ApplicationEventsInitialzed();
        }
        


        #region DateChanged

        /// <summary>
        /// A event that is raised when the current Date has changed.
        /// </summary>
		public static event EventHandler DateChanged;


        /// <summary>
        /// The timer used to shedule checks of the current Date.
        /// </summary>
        private static Timer DateChanged_timer;

        /// <summary>
        /// The DateTime that stores the date and time of the last time, DateChanged_CheckIfDateChanged() has been called.
        /// </summary>
        private static DateTime DateChanged_lastSavedDate;


        /// <summary>
        /// Raises the DateChanged event. 
        /// </summary>
        public static void OnDateChanged()
        {
            DateChanged(null, new EventArgs());
            
        }
        

        static void DateChanged_ApplicationEventsInitialzed()
        {
            DateChanged_lastSavedDate = DateTime.Now;

            SystemEvents.TimeChanged += new EventHandler(DateChanged_SystemEvents_TimeChanged);
            SystemEvents.PowerModeChanged += new PowerModeChangedEventHandler(SystemEvents_PowerModeChanged);
            SystemEvents.SessionSwitch += new SessionSwitchEventHandler(SystemEvents_SessionSwitch);

            DateChanged_timer = new Timer();
            DateChanged_timer.Tick += new EventHandler(DateChanged_timer_Tick);           

            DateChanged_resetTimer();
            
        }

        

        /// <summary>
        /// Calls DateChanged_CheckIfDateChanged() after DateChanged_timer has elapsed and resets the timer.
       /// </summary>
       /// <param name="sender"></param>
       /// <param name="e"></param>
        static void DateChanged_timer_Tick(object sender, EventArgs e)
        {
            DateChanged_CheckIfDateChanged();
        }

        /// <summary>
        /// Calls DateChanged_CheckIfDateChanged() after the system's time has changed.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        static void DateChanged_SystemEvents_TimeChanged(object sender, EventArgs e)
        {
            DateChanged_resetTimer();
        }

        /// <summary>
        /// Calls DateChanged_CheckIfDateChanged() after the system's power mode has changed.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        static void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
        {
            DateChanged_CheckIfDateChanged();
        }
        
        /// <summary>
        /// Calls DateChanged_CheckIfDateChanged() after the currently logged-in user has changed.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        static void SystemEvents_SessionSwitch(object sender, SessionSwitchEventArgs e)
        {
            DateChanged_CheckIfDateChanged();
        }

        /// <summary>
        /// Checks if the date has changed since the last time the method has been called and raises the DateChanged event if necessary.
        /// </summary>
        static void DateChanged_CheckIfDateChanged()
        {
            if (DateTime.Now.Date > DateChanged_lastSavedDate.Date)
            { OnDateChanged(); }

            DateChanged_lastSavedDate = DateTime.Now;
            DateChanged_resetTimer();
        }

        /// <summary>
        /// Resets DateChanged_timer. The interval will be set to the remaining milliseconds of the current day.
        /// </summary>
        static void DateChanged_resetTimer()
        {
            DateChanged_timer.Stop();            
            DateChanged_timer.Interval = 86400000 - (int)DateTime.Now.TimeOfDay.TotalMilliseconds;
            DateChanged_timer.Start();            
        }


        /// <summary>
        /// Detaches the event handlers for static events this object uses.
        /// </summary>
        public static void Dispose()
        {
            SystemEvents.TimeChanged -= DateChanged_SystemEvents_TimeChanged;
            SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;
            SystemEvents.SessionSwitch -= SystemEvents_SessionSwitch;
        }


        #endregion          
     
        #region ApplicationClosing
        
        /// <summary>
        /// Is raised when the Application is about to be closed.
        /// This event is declared in yaTDL.Core (a class library). You have to make sure that appplication that build on top of it raise the event as it will not be raised on it's own and code in yaTDL.Core depens on it.
        /// </summary>
        public static event EventHandler ApplicationClosing;


        public static void OnApplicationClosing()
        {
            ApplicationClosing(null, EventArgs.Empty);
        }

        #endregion



    }
}
